<?php

namespace common\models\db;

use Faker\Provider\Base;
use Yii;
use common\components\wtools\tools\ArrayHelper;

/**
 * This is the model class for table "{{%base_areas}}".
 *
 * @author
 * @property BaseAreas $parent
 * @property BaseAreas[] $children
 */
class BaseAreas extends \common\models\db\tables\BaseAreas
{
    const SCENARIO_TEST = 'test';

    public function attributeLabels()
    {
        $attributeLabels = parent::attributeLabels();
        $attributeLabels = ArrayHelper::merge($attributeLabels, []);
        return $attributeLabels;
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios = ArrayHelper::merge($scenarios, [
            self::SCENARIO_TEST => [],
        ]);
        return $scenarios;
    }

    const LEVEL_0 = 0;
    const LEVEL_1 = 1;
    const LEVEL_2 = 2;
    const LEVEL_3 = 3;
    const LEVEL_4 = 4;
    const LEVEL_5 = 5;
    const ID_CHINA = 100000000000;

    public static function getLevelDatas()
    {
        return [
            self::LEVEL_0 => ["中国(china)"],
            self::LEVEL_1 => ["省份(province)或直辖市"],
            self::LEVEL_2 => ["城市(city)"],
            self::LEVEL_3 => ["县或地区(county)"],
            self::LEVEL_4 => ["乡镇(town)"],
            self::LEVEL_5 => ["村庄(village)"],
        ];
    }

    /**
     * @return array
     */
    public static function getGangAoTaiProIds()
    {
        return [
            710000000000, // 台湾
            810000000000, // 香港特别行政区
            820000000000, // 澳门特别行政区
        ];
    }

    /**
     * @return false|mixed|BaseAreas[]
     */
    public static function getAllWithCache()
    {
        return Yii::$app->cache->getOrSet("db-BaseAreas-getAllWithCache", function () {
            return static::find()->all();
        }, null);
    }

    /**
     * @param $id
     * @return false|BaseAreas|mixed
     */
    public static function getByIdWithCache($id)
    {
        return Yii::$app->cache->getOrSet("db-BaseAreas-getByIdWithCache/{$id}", function () use ($id) {
            return static::findOne($id);
        }, null);
    }

    public function deleteCaches()
    {
        Yii::$app->cache->delete("db-BaseAreas-getAllWithCache");
        Yii::$app->cache->delete("db-BaseAreas-getByIdWithCache/{$this->id}");
    }

    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            $parent = $this->parent;
            if ($parent) {
                if ($parent->level + 1 != $this->level) {
                    $this->addError("level", "等级不匹配");
                    return false;
                }
                if (!is_numeric($this->id)) {
                    $this->addError("id", "地区编号必须为数字");
                    return false;
                }
                if (strlen($this->id) != 12) {
                    $this->addError("id", "地区编号长度必须为12位");
                    return false;
                }
                switch ($this->level) {
                    case self::LEVEL_1:
                        $remainder = $this->id % pow(10, 10);
                        if ($remainder) {
                            $this->addError("id", "地区编号后10位必须是0");
                            return false;
                        }
                        break;
                    case self::LEVEL_2:
                        $remainder = $this->id % pow(10, 8);
                        if ($remainder) {
                            $this->addError("id", "地区编号后8位必须是0");
                            return false;
                        }
                        $quotient = intval($this->id / pow(10, 10));
                        $pQuotient = intval($parent->id / pow(10, 10));
                        if ($quotient != $pQuotient) {
                            $this->addError("id", "地区编号前2位必须与上级地区编号一致");
                            return false;
                        }
                        break;
                    case self::LEVEL_3:
                        $remainder = $this->id % pow(10, 6);
                        if ($remainder) {
                            $this->addError("id", "地区编号后6位必须是0");
                            return false;
                        }
                        $quotient = intval($this->id / pow(10, 8));
                        $pQuotient = intval($parent->id / pow(10, 8));
                        if ($quotient != $pQuotient) {
                            $this->addError("id", "地区编号前4位必须与上级地区编号一致");
                            return false;
                        }
                        break;
                    default:
                        $this->addError("id", "未定义其他等级的错误处理");
                        return false;
                        break;
                }
                if (!in_array($this->level, [self::LEVEL_0, self::LEVEL_1])) {
                    $this->merger_name = $parent->merger_name .' '. $this->name;
                } else {
                    $this->merger_name = $this->name;
                }
            }
            $hasName = BaseAreas::find()
                ->andWhere(['!=', 'id', $this->id])
                ->andWhere(['pid' => $this->pid])
                ->andWhere(['name' => $this->name])
                ->count();
            if ($hasName > 0) {
                $this->addError("name", "该地区名称已存在");
                return false;
            }
            return true;
        }
        return false;
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        $this->deleteCaches();
    }

    public function afterRefresh()
    {
        parent::afterRefresh();
        $this->deleteCaches();
    }

    public function afterDelete()
    {
        parent::afterDelete();
        $this->deleteCaches();
    }


    # relations

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getParent()
    {
        return $this->hasOne(BaseAreas::className(), ['id' => 'pid']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getChildren()
    {
        return $this->hasMany(BaseAreas::className(), ['pid' => 'id']);
    }

    # static funs

    public function test()
    {
        $test = self::instance();
        $test->setScenario(self::SCENARIO_TEST);
        $test->save();
        var_dump($test->toArray());
    }

    # funs
}
